package com.bitdf.txing.search.service.impl;

import cn.dev33.satoken.stp.StpUtil;
import com.alibaba.fastjson.JSON;
import com.bitdf.txing.common.interceptor.LoginInterceptor;
import com.bitdf.txing.search.config.TxElasticConfig;
import com.bitdf.txing.search.constant.EsConstant;
import com.bitdf.txing.search.service.GroupUpdateService;
import com.bitdf.txing.search.to.GroupInfoTo;
import lombok.extern.slf4j.Slf4j;
import org.elasticsearch.action.DocWriteResponse;
import org.elasticsearch.action.get.GetRequest;
import org.elasticsearch.action.get.GetResponse;
import org.elasticsearch.action.update.UpdateRequest;
import org.elasticsearch.action.update.UpdateResponse;
import org.elasticsearch.client.RestHighLevelClient;
import org.elasticsearch.common.xcontent.XContentType;
import org.redisson.api.RLock;
import org.redisson.api.RedissonClient;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.io.IOException;
import java.util.concurrent.TimeUnit;

/**
 * @author Lizhiwei
 * @date 2023/1/26 20:55:28
 * 注释：
 */
@Service
@Slf4j
public class GroupUpdateServiceImpl implements GroupUpdateService {

    @Autowired
    RedissonClient redissonClient;

    @Autowired
    RestHighLevelClient restHighLevelClient;


    /**
     * 关闭活动
     *
     * @param groupId
     * @return
     * @throws IOException
     */
    @Override
    public Boolean modifyStatus(Long groupId) throws IOException {
        //权限校验：判断是否是目标组团的发起人
        GetRequest getRequest = new GetRequest(EsConstant.GROUP_INDEX, groupId.toString());
        GetResponse response1 = restHighLevelClient.get(getRequest, TxElasticConfig.COMMON_OPTIONS);
        GroupInfoTo groupInfoTo = JSON.parseObject(response1.getSourceAsString(), GroupInfoTo.class);
        long userId = StpUtil.getLoginIdAsLong();
        if (groupInfoTo.getUserId() != userId) {
            log.info("当前用户：{} 不是组团{}的发起人，无权限关闭", userId, groupId);
            return false;
        }
        //校验通过则更新组团状态
        UpdateRequest updateRequest = new UpdateRequest(EsConstant.GROUP_INDEX, groupId.toString());
        updateRequest.doc(XContentType.JSON, "status", 3);
        UpdateResponse response = restHighLevelClient.update(updateRequest, TxElasticConfig.COMMON_OPTIONS);
        if (response.getShardInfo().getSuccessful() == 1) {
            return true;
        } else {
            return false;
        }
    }

    /**
     * 使组团的一些字段作加或减运算
     *
     * @param groupId
     * @return
     * @throws IOException
     */
    @Override
    public Boolean increOrDcre(Long groupId, Integer opsValue, String target) throws IOException {
        //TODO 看看是否可以优化为直接自增
        //上锁，避免并发问题
        RLock lock = redissonClient.getLock("increOrDcre");
        lock.lock(3, TimeUnit.SECONDS);
        UpdateResponse response1;
        try {
            GetRequest getRequest = new GetRequest(EsConstant.GROUP_INDEX, groupId.toString());
            GetResponse response = restHighLevelClient.get(getRequest, TxElasticConfig.COMMON_OPTIONS);
            GroupInfoTo groupInfoTo = JSON.parseObject(response.getSourceAsString(), GroupInfoTo.class);

            UpdateRequest updateRequest = new UpdateRequest(EsConstant.GROUP_INDEX, groupId.toString());
            Integer oldValue = 0;
            switch (target) {
                case "likeCount":
                    oldValue = groupInfoTo.getLikeCount();
                    break;
                case "collectCount":
                    oldValue = groupInfoTo.getCollectCount();
                    break;
                case "commentCount":
                    oldValue = groupInfoTo.getCommentCount();
                    break;
                case "viewCount":
                    oldValue = groupInfoTo.getViewCount();
                    break;
                case "currentPersonCount":
                    oldValue = groupInfoTo.getCurrentPersonCount();
                    break;
            }
            updateRequest.doc(XContentType.JSON, target, oldValue + opsValue);
            response1 = restHighLevelClient.update(updateRequest, TxElasticConfig.COMMON_OPTIONS);
        } finally {
            lock.unlock();
        }
        if (response1.getShardInfo().getSuccessful() == 1) {
            return true;
        } else {
            return false;
        }
    }

    /**
     * 更新组团
     *
     * @param groupInfoTo
     * @return
     */
    @Override
    public boolean updateGroup(GroupInfoTo groupInfoTo) throws IOException {
        UpdateRequest updateRequest = new UpdateRequest(EsConstant.GROUP_INDEX, groupInfoTo.getId().toString());
        String s = JSON.toJSONString(groupInfoTo);
        updateRequest.doc(s, XContentType.JSON);
        UpdateResponse response = restHighLevelClient.update(updateRequest, TxElasticConfig.COMMON_OPTIONS);
        return response.getResult() == DocWriteResponse.Result.UPDATED;
//        return response.getShardInfo().getSuccessful() == 1 ? true : false;
    }
}
